# pylint:disable=I1101:c-extension-no-member
"""network"""
import platform
import socket
import time

import netifaces
import psutil

from lib.logger import logger


def find_available_port(exclude_port=None):
    """find available port"""

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(("localhost", 0))
        _, port = s.getsockname()
        if exclude_port is not None and port == exclude_port:
            _, new_port = s.getsockname()
            return new_port
    return port


def interface_exists(interface_name):
    """check if interface exists"""

    interfaces = netifaces.interfaces()
    if interface_name in interfaces:
        return True
    else:
        return False


def get_network_interface_ip(interface_name):
    """get network interface ip"""

    if interface_exists(interface_name) is False:
        return None

    addresses = netifaces.ifaddresses(interface_name).get(netifaces.AF_INET)
    if addresses:
        return addresses[0]["addr"]

    return None


def get_external_interface():
    """get external interface"""

    gateways = netifaces.gateways()
    default_gateway = gateways["default"][netifaces.AF_INET][1]  # 获取默认网关的IPv4地址

    interfaces = netifaces.interfaces()
    for interface in interfaces:
        if interface == "lo":  # 排除回环接口
            continue
        addresses = netifaces.ifaddresses(interface)
        if netifaces.AF_INET in addresses:
            for address in addresses[netifaces.AF_INET]:
                if (
                    "addr" in address
                    and address["addr"] != "127.0.0.1"
                    and address["addr"] != default_gateway
                ):
                    return interface

    return None


def get_ip_address():
    """get ip address"""

    system = platform.system()

    ip_addr = None

    if system == "Linux":
        ip_addr = get_network_interface_ip("eth0")
        if not ip_addr:
            interface_name = get_external_interface()
            logger.info(f"the external interface is {interface_name}")
            if interface_name:
                ip_addr = get_network_interface_ip(interface_name)

    elif system == "Darwin":
        ip_addr = get_network_interface_ip("en0")

    logger.info(f"get current {system} ip address: {ip_addr}")
    return ip_addr


def get_network_speed(interval=1):
    """get network speed"""

    net_io_start = psutil.net_io_counters()
    bytes_sent_start = net_io_start.bytes_sent
    bytes_recv_start = net_io_start.bytes_recv

    time.sleep(interval)

    net_io_end = psutil.net_io_counters()
    bytes_sent_end = net_io_end.bytes_sent
    bytes_recv_end = net_io_end.bytes_recv

    _download_speed = (bytes_recv_end - bytes_recv_start) / interval / 1024  # kb/s
    _upload_speed = (bytes_sent_end - bytes_sent_start) / interval / 1024  # kb/s

    return _download_speed, _upload_speed
